#ifndef _ABSYN_H
#define _ABSYN_H
#include <iostream>
#include <string>
#include <vector>
#include <bitset>
#include "list"
#include "typemap.h"


using namespace std;


enum DeclarationKind {//声明种类
    PROGRAM=1,//程序
    PROGRAMHEAD,//程序头
    PROGRAMBODY,//程序体
	FUNCTIONHEAD,//函数头
	PROCEDUREHEAD,//过程头
	DK_CONST,//常量声明
	TYPE,//类型声明
    DK_VAR,//变量声明
	VAR_PARA,//参数_变量
	VAL_PARA//参数_值
};


enum ExpressionKind {//表达式种类
    EK_ID = 11,//标识符
    OP,//操作
    EK_CONST,//常量表达式
    EK_CASE,//case语句
    FUNC_ID,//函数名
    FUNC_SYS//系统函数
};


enum ExpressionType {//表达式类型
    VOID = 17,//空
    INT,//int
    REAL,//real
    CHAR,//char
    BOOL,//bool
    ET_ARRAY,//数组
    ET_SIMPLE_LIMIT//范围
};

enum OperationKind {//操作
    TO = 24,//to
    DOWNTO,//downto
    READ,//read
    WRITE,//write
    PLUS,//+
    MINUS,//-
    MUL,//*
    DIV,//除
    MOD,//取余
    LT,//小于
    LE,//小于等于
    GT,//大于
    GE,//大于等于
    EQUAL,//相等
    UNEQUAL,// 不等
    NOT, //非
    OR, //或
    AND,// 与
    
};


enum StatementKind {//流程
    ASSIGN=42,//赋值
    IF,//条件
    REPEAT,//重复
    WHILE,//while循环
    FOR,//for循环
    SK_CASE,//case
    PROC_ID,//过程名
    PROC_SYS//系统过程 read write
};


enum TypeKind {//类型
    SIMPLE_SYS=50,//系统定义类型 char int real bool
    TK_SIMPLE_LIMIT,//范围
    TK_ARRAY,//数组
    TK_RECORD//记录
};

typedef class TreeDefine *TreeNode;
/* define in symboldefine.h*/
class RecordDefinition;
class SubBoundDefinition;
class ArrayDefinition;

struct Object
{
    int flag;
	int _int;
	double _double;
	string _string;

	RecordDefinition* rd;//5 enum
	list<struct Object> lo;//6 record
	SubBoundDefinition* sd;//7 array index
	ArrayDefinition* ad;//8 array
};

class TreeDefine//语法树
{
    private:
	vector<TreeNode> childNode;//子节点
    TreeNode siblingNode = NULL;//兄弟节点
    int nodeType = 0;//节点类型
   	Object attribute;//节点属性
    ExpressionType expressionType;//表达式类型,若节点为表达式
    ExpressionType runtimeType;//
    int lineNumber = 0;//行号
    int columnNumber = 0;//列号
    bitset<32> bitSet;//printTree()用到

    public:
    //构造函数
    TreeDefine() {}

	TreeDefine(ExpressionKind nodeType, int lineNumber):nodeType(nodeType),lineNumber(lineNumber){ this->expressionType = VOID;}

	TreeDefine(DeclarationKind nodeType, int lineNumber):nodeType(nodeType),lineNumber(lineNumber) {}

	TreeDefine(TypeKind nodeType, int lineNumber):nodeType(nodeType),lineNumber(lineNumber) {}

	TreeDefine(StatementKind nodeType, int lineNumber):nodeType(nodeType),lineNumber(lineNumber) {}

    TreeDefine(TreeNode first, TreeNode second, OperationKind op, int lineNumber) {
  		this->nodeType = OP;
		this->attribute._int = op;
		this->attribute.flag = 4;//expression type
		this->lineNumber = lineNumber;
		this->addChild(first);
		this->addChild(second);
    }

    TreeDefine(OperationKind op, TreeNode child, int lineNumber) {
        this->nodeType = FUNC_SYS;
        this->attribute._int = op;
		this->attribute.flag = 4;//type
        this->lineNumber = lineNumber;
		this->addChild(child);
    }

    vector<TreeNode> getChildren() const;//返回子节点
    void addChild(TreeNode node);//添加子节点

    TreeNode getSibling() const;//返回兄弟节点
    void setSibling(TreeNode siblingNode);//添加兄弟节点

    int getLineNumber() const;//行号
    void setLineNumber(int lineNumber);//设置行号

    int getNodeType() const;//返回节点类型
	void setNodeType(int nodeType);//设置节点类型

    //节点属性
    Object getAttribute() const;//返回节点属性
    void setAttribute(Object attribute);//设置属性
    void setAttribute(int attribute,int flag);
    void setAttribute(double attribute);
    void setAttribute(string attribute);

    ExpressionType getExpType() const;//返回表达式类型
    void setExpType(ExpressionType expressionType);//设置表达式类型

    ExpressionType getRunTimeType() const;
    void setRunTimeType(ExpressionType runtimeType);

    //打印语法树
    void printTree(TreeNode root, int level);
};

#endif
